package com.tx.websocket.demo.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import com.tx.websocket.demo.common.BusinessException;
import com.tx.websocket.demo.common.OffsetBean;
import com.tx.websocket.demo.dao.RoleDao;
import com.tx.websocket.demo.dao.UserDao;
import com.tx.websocket.demo.dto.UserRoleDto;
import com.tx.websocket.demo.model.Role;
import com.tx.websocket.demo.model.User;
import com.tx.websocket.demo.model.UserRoleRel;
import com.tx.websocket.demo.service.UserService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.crypto.hash.Sha256Hash;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


@Service
public class UserServiceImpl implements UserService {

    @Resource
    private UserDao userDao;

    @Resource
    private RoleDao roleDao;

    @Transactional
    @Override
    public Integer addUser(User user) {
        user.setCreateTime(new Date());
        user.setPassword(new Sha256Hash(user.getPassword()).toHex());
        return userDao.addUser(user);
    }

    @Transactional(readOnly = true)
    @Override
    public List<User> listUser(User user, OffsetBean offsetBean) {
        return userDao.listUser(user, offsetBean);
    }

    @Transactional(readOnly = true)
    @Override
    public User getUserByPrimaryKey(Long id) {
        return userDao.getUserByPrimaryKey(id);
    }

    @Transactional
    @Override
    public Integer delUserByPrimaryKey(Long id) {
        User user = userDao.getUserByPrimaryKey(id);
        user.setEnable(false);
        user.setUpdateTime(new Date());
        return userDao.updateUser(user);
    }

    @Transactional
    @Override
    public Integer updateUser(User user) {
        user.setUpdateTime(new Date());

        if(StringUtils.isNotBlank(user.getPassword()))
            user.setPassword(new Sha256Hash(user.getPassword()).toHex());

        return userDao.updateUser(user);
    }

    @Override
    public User getUserByUsername(String username) {
        return userDao.getUserByUsername(username);
    }

    @Override
    public Integer totalUser(User user) {
        return userDao.totalUser(user);
    }

    @Transactional(readOnly = true)
    @Override
    public UserRoleDto doUserRoleRel(Long userId) {
        User user = userDao.getUserByPrimaryKey(userId);

        if(user == null)
            throw new BusinessException("用户不存在");

        List<Role> roles = roleDao.listRole(null, null);

        List<Role> haveRoles = roleDao.listRoleByUserId(userId);

        if(CollectionUtils.isEmpty(roles))
            throw new BusinessException("无可关联的角色");

        for(Role r : roles) {
            if (haveRoles != null && haveRoles.contains(r))
                r.setBeHave(true);
        }

        user.setPassword(null);
        return new UserRoleDto(user, roles);
    }

    @Transactional
    @Override
    public Integer doUserRoleBinding(Long userId, List<Long> roleIds) {
        userDao.delUserRoleById(userId);
        int count = 0;
        if(CollectionUtils.isNotEmpty(roleIds)) {
            List<UserRoleRel> userRoleRels = new ArrayList<>();
            for(Long roleId : roleIds) {
                UserRoleRel userRoleRel = new UserRoleRel();
                userRoleRel.setRoleId(roleId);
                userRoleRel.setUserId(userId);
                userRoleRels.add(userRoleRel);
            }
            userDao.insertUserRole(userRoleRels);
        }
        return count;
    }

}
